//文件名：APP_RemoteControl
//功能：远程控制应用程序存放
//创建时间：2021年10月27日
//作者：dowson
//email：dowson.tseng@gmail.com
#include "system_init.h"
#include "APP_RemoteControl.h"
#include "Can_Refresh.h"
#include "Wireless_init.h"
#include "Wireless_Tcp.h"
#include "CanIf.h"
#include "AES.h"

#define APP_REMOTE_LOG 0
#define SERVER_CMD_LOG 0

extern tSystemData SystemData;
extern tVehicleState VehicleState;
tSendRemoteControl sendSpeedLimit;
tSendRemoteControl sendDoorLock;
static uint8_t getCmdMark=0;

tServerCmdBuffer RemoteBuffer[SERVER_CMD_BUFFER_SIZE+1]; //+1防止越界  
tArrayQueue ServerCmdQueue;


static void MarkControlBit(remoteControlType mark_type,uint8_t state);
static uint8_t ServerCmdRequest(void);


//标记对应标志位
void MarkControlBit(remoteControlType mark_type,uint8_t state){
    //LOG_DBG("in MarkControlBit orginal:%4x,mark_type:%4x,state:%d,",SystemData.remoteCtrl.control_mark,mark_type,state);
    switch (mark_type)
    {
    case CTR_POWER_ON:
        SystemData.remoteCtrl.control_mark &= (uint32_t)~POWER_ON_BIT;
        SystemData.remoteCtrl.control_mark |= (state<<POWER_ON_BIT_BEGIN);
        break;
    case CTR_LOCK_MARK:
        SystemData.remoteCtrl.control_mark &= (uint32_t)~LOCK_MARK_BIT;
        SystemData.remoteCtrl.control_mark |= (state<<LOCK_MARK_BIT_BEGIN);
        break;
    case CTR_FIND_CAR:
        SystemData.remoteCtrl.control_mark &= (uint32_t)~FIND_CAR_BIT;
        SystemData.remoteCtrl.control_mark |= (state<<FIND_CAR_BIT_BEGIN);
        break;
    case CTR_SPEED_LIMIT:
        SystemData.remoteCtrl.control_mark &= (uint32_t)~SPEED_LIMIT_BIT;
        SystemData.remoteCtrl.control_mark |= (state<<SPEED_LIMIT_BIT_BEGIN);
        break;
    case CTR_SPEED_EN:
        SystemData.remoteCtrl.control_mark &= (uint32_t)~SPEED_EN_BIT;
        SystemData.remoteCtrl.control_mark |= (state<<SPEED_EN_BIT_BEGIN);
        break;  
    default:
        break;
    }
}
//解除对应标志位,恢复为默认状态
void ClearControlBit(remoteControlType mark_type){
    switch (mark_type)
    {
    case CTR_POWER_ON:
        SystemData.remoteCtrl.control_mark &= ~(uint32_t)POWER_ON_BIT;
        SystemData.remoteCtrl.control_mark |= (0x00<<POWER_ON_BIT_BEGIN);
        break;
    case CTR_LOCK_MARK:
        SystemData.remoteCtrl.control_mark &= ~(uint32_t)LOCK_MARK_BIT;
        SystemData.remoteCtrl.control_mark |= (0x00<<LOCK_MARK_BIT_BEGIN);
        break;
    case CTR_FIND_CAR:
        SystemData.remoteCtrl.control_mark &= ~(uint32_t)FIND_CAR_BIT;
        SystemData.remoteCtrl.control_mark |= (0x00<<FIND_CAR_BIT_BEGIN);
        break;
    case CTR_SPEED_LIMIT:
        SystemData.remoteCtrl.control_mark &= ~(uint32_t)SPEED_LIMIT_BIT;
        SystemData.remoteCtrl.control_mark |= (0x00<<SPEED_LIMIT_BIT_BEGIN);
        break;
    case CTR_SPEED_EN:
        SystemData.remoteCtrl.control_mark &= ~(uint32_t)SPEED_EN_BIT;
        SystemData.remoteCtrl.control_mark |= (0x00<<SPEED_EN_BIT_BEGIN);
        break;
    default:
        break;
    }
}


//远程控制初始化函数
void RemoteControlInit(void){
    //LOG_DBG("init control_mark:%04x\r\n",SystemData.remoteCtrl.control_mark);
    if(SystemData.remoteCtrl.control_mark == 0xffffffff){
        SystemData.remoteCtrl.control_mark = DEFAULT_CONTROL_PARAM;
        SystemData.remoteCtrl.limit_speed_size = 0;
        SystemData.remoteCtrl.default_state = 0;
        //LOG_DBG("no control param set default:%04x\r\n",SystemData.remoteCtrl.control_mark);
    }
    MarkControlBit(CTR_LOCK_MARK,0);
    MarkControlBit(CTR_FIND_CAR,0);
    MarkControlBit(CTR_POWER_ON,0);
}
//远程控制反始化函数
void RemoteControlDeinit(void){
    
}

//远程控制执行主函数 500ms周期性发送消息
void RemoteControlHandleMain(void)
{
    RemoteControlSendOut();
}


//按照协议解析远程控制数据
//[21] 加密方式
//[22][23]数据长度
//[24][25][26][27][28][29]时间
//[30] 锁车标志
//[31] 限速速度值
//[32]远程寻车 
//[33]远程锁门
//[34]上下电
//[35]校验
void RemoteControlRecive(uint8_t *databuf,uint16_t data_len){
	uint8_t vin[17] = {0};
	// uint8_t encrypt=0;
	// uint16_t dataLen;
    // uint16_t i=0;

    ServerCmdRequest();
    getCmdMark = 10;
    memcpy(vin,&databuf[4],17);
#if APP_REMOTE_LOG
    LOG_DBG("get remote vin:%s\n",vin);
#endif
    // encrypt = databuf[21];
    // dataLen = (uint16_t)(databuf[22])<<8 + databuf[23];
#if APP_REMOTE_LOG
    LOG_DBG("remote data len:%d\n",dataLen);
	LOG_DBG("cmd source:");
	for(i=0;i<data_len;i++)
		LOG_DBG("%02x",databuf[i]);
	LOG_DBG("\r\n");
#endif 
    switch (databuf[30])
    {
    case SPEED_LIMIT:
        MarkControlBit(CTR_SPEED_EN,TRUE);
        MarkControlBit(CTR_SPEED_LIMIT,FALSE);  //使能限速，状态是逻辑反的
        if(databuf[31]<=60)
            SystemData.remoteCtrl.limit_speed_size = databuf[31];
        break;
    case SPEED_LOCK:
        MarkControlBit(CTR_SPEED_LIMIT,TRUE);
        MarkControlBit(CTR_SPEED_EN,FALSE); //使能锁车，状态是逻辑反的
        SystemData.remoteCtrl.limit_speed_size = 0;
        break;
    case SPEED_UNLOCK:
        MarkControlBit(CTR_SPEED_LIMIT,TRUE);
        MarkControlBit(CTR_SPEED_EN,TRUE);
        SystemData.remoteCtrl.limit_speed_size = 71;
        break;        
    default:
        break;
    }
#if APP_REMOTE_LOG
    LOG_DBG("databuf[30]:%02x,[31]:%02x,limit_speed_size:%d\r\n",databuf[30],databuf[31],SystemData.remoteCtrl.limit_speed_size);
#endif
    if(databuf[32]){
        MarkControlBit(CTR_FIND_CAR,TRUE);
    }
#if APP_REMOTE_LOG
    LOG_DBG("databuf[32]:%02x,control_mark:%d\r\n",databuf[32],SystemData.remoteCtrl.control_mark);
#endif
    if(0x01 == databuf[33]){
        MarkControlBit(CTR_LOCK_MARK,0X01);
    }else if(0x02 == databuf[33]){
        MarkControlBit(CTR_LOCK_MARK,0X02);
    }
#if APP_REMOTE_LOG
    LOG_DBG("databuf[33]:%02x,control_mark:%04x\r\n",databuf[33],SystemData.remoteCtrl.control_mark);
#endif
    if(0x01 == databuf[34]){
        MarkControlBit(CTR_POWER_ON,0x01);
    }else if(0x02 == databuf[34]){
        MarkControlBit(CTR_POWER_ON,0x02);
    }else if(0x03 == databuf[34]){
        MarkControlBit(CTR_POWER_ON,0x03);
    }     
#if APP_REMOTE_LOG
    LOG_DBG("databuf[34]:%02x,control_mark:%04x\r\n",databuf[34],SystemData.remoteCtrl.control_mark);  
#endif 
    //刷新MCU回传状态
    ControlStateVehicleInit();
    SaveSysParamToFlash();
}
//服务器应答函数
static uint8_t ServerCmdRequest(void)
{
	uint8_t buf[100];
	unsigned short set[4]={0,0x91,1,6};
	// uint16_t i=0,j=24;
	uint8_t time[16];

	memset(buf,0x00,sizeof(buf));
	GBT_Package_Config(buf,set);
	GetSystemTime(time);
	buf[24] = time[0];
	buf[25] = time[1];
	buf[26] = time[2];
	buf[27] = time[3];
	buf[28] = time[4];
	buf[29] = time[5];
	buf[30]=Bcc_Check(buf,30);
#if APP_REMOTE_LOG
	LOG_DBG("remote ack:");
	for(i=0;i<64;i++)
		LOG_DBG("%02x",buf[i]);
	LOG_DBG("\r\n");
#endif
	wirelesess_TCP_send_original_data(buf, 32);
#if APP_REMOTE_LOG
    LOG_DBG("current cmd state is:%4x\r\n",SystemData.remoteCtrl.control_mark);
    LOG_DBG("current cmd limit_speed_size is:%d\r\n",SystemData.remoteCtrl.limit_speed_size);
#endif
	return 0;
}

//控制状态初始化
uint8_t ControlStateVehicleInit(void){
    VehicleState.speedLimitState = 0xff;
    VehicleState.speedLimitSize = 0xff;
    VehicleState.vehicleRunState = 0xff;
    VehicleState.LFdoorState = 0xff;
    VehicleState.LFdoorlockState = 0xff;
    VehicleState.LWindowState = 0xff;
    VehicleState.RWindowState = 0xff;

    return 0;
}

//车辆状态回传
uint8_t ControlResultUpload(void)
{
	uint8_t buf[100];
	unsigned short set[4]={0x11,0x11,0xfe,13};
	// uint16_t i=0,j=24;
	uint8_t time[16];

    // VehicleState.vehicleRunState;
    // VehicleState.LFdoorState;
    // VehicleState.LFdoorlockState;
    // VehicleState.LWindowState;
    // VehicleState.RWindowState;
    if(!IsOnlineCanDevice(CanDevice_MCU))
    {
        //LOG_DBG("remote state up warning!-no have MCU data\r\n");
        ControlStateVehicleInit();
    }

	memset(buf,0x00,sizeof(buf));
	GBT_Package_Config(buf,set);
	GetSystemTime(time);
	buf[24] = time[0];
	buf[25] = time[1];
	buf[26] = time[2];
	buf[27] = time[3];
	buf[28] = time[4];
	buf[29] = time[5];
    buf[30] = VehicleState.speedLimitState;
    buf[31] = VehicleState.speedLimitSize;
    buf[32] = VehicleState.vehicleRunState;
    buf[33] = VehicleState.LFdoorState;
    buf[34] = VehicleState.LFdoorlockState;
    buf[35] = VehicleState.LWindowState;
    buf[36] = VehicleState.RWindowState;
	buf[37] = Bcc_Check(buf,38);
#if APP_REMOTE_LOG
	LOG_DBG("remote state up:");
	for(i=0;i<64;i++)
		LOG_DBG("%02x",buf[i]);
	LOG_DBG("\r\n");
#endif
	wirelesess_TCP_send_original_data(buf, 39);
	return 0;
}
//上电启动发布函数


//消息发布函数
void RemoteControlSendOut(void)
{
    static uint8_t life_heartbeat;
    PduInfoType TimeData;
    uint8_t CAN_DATA[8];
    extern tVehicleState VehicleState;

    if(getCmdMark)
    {
        getCmdMark--;
        if(1==getCmdMark)
        {
            ControlResultUpload();
        }
    }
    memset(CAN_DATA,0x00,sizeof(CAN_DATA));
    CAN_DATA[0] = (uint8_t)SystemData.remoteCtrl.control_mark;
    CAN_DATA[1] = SystemData.remoteCtrl.limit_speed_size;
    if(life_heartbeat==255) life_heartbeat=0;
    CAN_DATA[7] = life_heartbeat++;

    TimeData.MetaDataPtr = NULL;
    TimeData.SduDataPtr = CAN_DATA;
    TimeData.SduLength = 8;
    CanIf_Transmit(CANIF_TXPDU_0C65D0D2_TBOX2VCU_TX, &TimeData);
}

//CAN总线数据车辆状态采集回调,8byte//接收ID：
void CAN_RemoteVehicleStateCallback(uint8_t* can_databuf){
    //VehicleState.vehicleRunState = can_databuf[0]&0x03;
    switch (can_databuf[0]&0x03)
    {
    case 0x01:
        VehicleState.chargeState = 0x00;
        break;   
    case 0x02:
        VehicleState.chargeState = 0x01;
        break;
    case 0x03:
        VehicleState.chargeState = 0x02;
        break;  
    default:
        VehicleState.chargeState = 0xff;
        break;
    }

    switch ((can_databuf[0]>>4)&0x03)
    {
    case 0x01:
        VehicleState.LFdoorState = 0x00;
        break;   
    case 0x02:
        VehicleState.LFdoorState = 0x01;
        break;    
    default:
        VehicleState.LFdoorState = 0xff;
        break;
    }
    //VehicleState.LFdoorState = (can_databuf[0]>>4)&0x03;
    switch ((can_databuf[0]>>6)&0x03)
    {
    case 0x01:
        VehicleState.LFdoorlockState = 0x00;
        break;   
    case 0x02:
        VehicleState.LFdoorlockState = 0x01;
        break; 
    default:
        VehicleState.LFdoorlockState = 0xff;
        break;
    }    
    //VehicleState.LFdoorlockState = (can_databuf[0]>>6)&0x03;
    switch ((can_databuf[2])&0x07)
    {
    case 0x01:
        VehicleState.speedLimitState = 0x00;
        break;   
    case 0x02:
        VehicleState.speedLimitState = 0x01;
        break; 
    case 0x03:
        VehicleState.speedLimitState = 0x02;
        break; 
    case 0x04:
        VehicleState.speedLimitState = 0x03;
        break;   
    default:
        VehicleState.speedLimitState = 0xff;
        break;
    }     
    VehicleState.LWindowState = (can_databuf[1])&0x03;
    VehicleState.RWindowState = (can_databuf[1]>>2)&0x03;
    //VehicleState.speedLimitState = can_databuf[2]&0x07;
    VehicleState.speedLimitSize = can_databuf[3];
}

void R_GBT_IdPolling(uint8_t *data,uint16_t len,uint8_t tcpIndex)  	//	下行数据ID轮询		
{
	extern uint8_t R_Sys_Param_Setting_CMP;
	extern tOTA_Request OTA_Request;
    extern unsigned char Data_Analysis[];
    extern uint8_t SERVER_TIME[];

    memcpy(Data_Analysis,data,len);
    
#if NEED_LOG
	//LOG_DBG("GBT_IdPolling data[2] is: %d\n",data[2]);
#endif
    //获得服务器时间备份
    // SERVER_TIME[0] = data[24];
    // SERVER_TIME[1] = data[25];
    // SERVER_TIME[2] = data[26];
    // SERVER_TIME[3] = data[27];
    // SERVER_TIME[4] = data[28];
    // SERVER_TIME[5] = data[29];
    // if(CheckTime(SERVER_TIME)){
    //     SERVER_TIME[7] = 1;  //时间有效性
    // }else{
    //     SERVER_TIME[7] = 0;
    // }
    // LOG_DBG("get server time-%d: %d,%d,%d-%d,%d,%d\n",SERVER_TIME[6],SERVER_TIME[0],SERVER_TIME[1],SERVER_TIME[2],SERVER_TIME[3],SERVER_TIME[4],SERVER_TIME[5]);
	switch(data[2])
	{
		case 0x01:
			GBT_data_sum_handle.GBT32960_GlobalVariables_Variables.Response[0] = data[3];
		break;
		case 0x02:
			GBT_data_sum_handle.GBT32960_GlobalVariables_Variables.Response[1] = data[3];
		break;
		case 0x03:
			GBT_data_sum_handle.GBT32960_GlobalVariables_Variables.Response[2] = data[3];
		break;
		case 0x04:
			GBT_data_sum_handle.GBT32960_GlobalVariables_Variables.Response[3] = data[3];
		break;
		case 0x05:
			GBT_data_sum_handle.GBT32960_GlobalVariables_Variables.Response[4] = data[3];
		break;
		case 0x06:
			GBT_data_sum_handle.GBT32960_GlobalVariables_Variables.Response[5] = data[3];
		break;
		case 0x07:
			GBT_data_sum_handle.GBT32960_GlobalVariables_Variables.Response[6] = data[3];
		break;
		case 0x08:
			GBT_data_sum_handle.GBT32960_GlobalVariables_Variables.Response[7] = data[3];
		break;
		case 0x80:		//查询命令
			//LOG_DBG("this is server check\n");
			GBT_search_information(tcpIndex);
			GBT_data_sum_handle.GBT32960_GlobalVariables_Variables.Response[8] = data[3];
		break;
		case 0x81:  	//设置命令
			//LOG_DBG("this is server setting\n");
			if(R_Sys_Param_Setting_CMP){
				R_Sys_Param_Setting_CMP = 0;
				//防止平凡操作数组越界
				GPT_set_information(tcpIndex);
			}
			GBT_data_sum_handle.GBT32960_GlobalVariables_Variables.Response[9] = data[3];
		break;
		case 0x82:  	//车载终端控制命令
            //LOG_DBG("this is server control\n");
			GBT_Terminal_Control(tcpIndex);
			GBT_data_sum_handle.GBT32960_GlobalVariables_Variables.Response[10] = data[3];
		break;

		case 0x90: //OTA升级
			//LOG_DBG("this is ota command\n");
                //LOG_DBG("updateMode1:%d\r\n",OTA_Request.updateMode);
			//常规模式下才能升级
			if(SYS_NORMAL == GetSysRunState()){
				GetPushMsgData(data,len);
			}
            //LOG_DBG("updateMode2:%d\r\n",OTA_Request.updateMode);

		break;
		case 0x91:	//远程控制
#if REMOTE_CONTROL
            //LOG_DBG("this is remote cmd,len:%d\n",len);
            RemoteControlRecive(data,len);
#endif
		break;
		case 0x95: //OTA升级URL
            //LOG_DBG("this is ota url\n");
			if(SYS_NORMAL == GetSysRunState()){
			 GetDownloadURL(data,len);
			}			
		break;
		default:
		break;
	}
    if(data[2<0x80]){
        WakeUpThird(TASK_SERVER_WAIT);
    }
}

//加解密
GBT32960_MyLocker R_GBT32960_DataDecryption (uint8_t* Origin,uint16_t data_len,const uint8_t *key){

	uint8_t  buff[SERVER_CMD_BUFFER_NODE_SIZE];
	uint16_t len = 0;
	uint8_t  len_Remainder = 0;

    memset(buff,0x00,sizeof(buff));
	memcpy(buff,Origin,data_len);
    
	if(buff[21] == 0x01){
		return MyLocker_Blank;
	}else if(buff[21] == 0x02){

		//RSA还未上。
	}else if(buff[21] == 0x03){
        len = buff[22];
        // len <= 8;
        len |= buff[23];
        //LOG_DBG("recode len:%d",len);
		len_Remainder = len % 16;
		if(len_Remainder != 0){
			len = len + (16-len_Remainder);
		}
		if(Decode_AES128(&buff[24],&Origin[24],len,key)){
			return MyLocker_Failure;
		}
		return MyLocker_Aes128;
	}
    return MyLocker_Failure;
    //LOG_DBG("recode buff[21]:%d,buff[22]:%d,buff[23]:%d-len:%d\r\n",buff[21],buff[22],buff[23],len);
}


//远程服务器控制指令相关的数据处理
uint8_t R_Sys_Param_Setting_CMP = 1;



static void R_GBT_DownstreamData_Check(char *server_cmd_rxbuff,uint16_t len,uint8_t tcpIndex)  //下行数据检查
{
    const char *begin_start_str = "##";
    uint8_t *str_begin;
	uint16_t i=0;
    uint8_t key1[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
	
    str_begin = (uint8_t *)strstr(server_cmd_rxbuff, begin_start_str);
    if(str_begin)
    {
        // str_begin++;
        if(!GBT_BccVerify(str_begin))
        {
            R_GBT32960_DataDecryption(str_begin, len, key1);
            R_GBT_IdPolling(str_begin, len, tcpIndex);
#if 0
            LOG_DBG("Bcc success:\n");
            LOG_DBG("recode data:");
            for(i=0;i<len;i++)
                LOG_DBG("%02x ",str_begin[i]);
            LOG_DBG("\r\n");
#endif
        }
        else
        {
            LOG_ERR("Bcc error:\n");
            for(i=0;i<len;i++)
                LOG_DBG("%02x ", str_begin[i]);
            LOG_DBG("len - %d.\r\n", len);
        }
    }
    else
    {
        //LOG_DBG("wasnt cmd:%s\n",str_begin);
    }
    memset(server_cmd_rxbuff,0x00,len);
	R_Sys_Param_Setting_CMP = 1;
}



//--------------------------------------------------------------------------------------------------------


void ServerCmdReciveInit(void){
    RemoteControlInit(); //远程控制相关
    ArrayQueue_Inint(&ServerCmdQueue,RemoteBuffer,0x00,SERVER_CMD_BUFFER_SIZE,sizeof(tServerCmdBuffer));//SERVER_CMD_BUFFER_NODE_SIZE
}
//参数查询与控制
void DownstreamData_Check_Main(void){
    tServerCmdBuffer serverCmd;
    if(!ArrayQueue_IsEmput(&ServerCmdQueue)){
        ArrayQueue_GetDataFromHead(&ServerCmdQueue,&serverCmd);  
#if SERVER_CMD_LOG
        LOG_DBG("in queue have cmd:%d-%s\n",serverCmd.data_len,serverCmd.data);
#endif
        R_GBT_DownstreamData_Check((char *)serverCmd.data,serverCmd.data_len,1);  
    }
}

//服务器发送相关的数据中断回调处理函数
void ServerCmdCallback(char *data, uint32_t size)
{    
    LOG_DBG("%s-data:%s \r\n", __FUNCTION__, data);
    R_GBT_DownstreamData_Check(data, size, TCP_index1);
    Set_Wireless_Step_State(WIRE_ORIGIN_SEND, true);
    if(get_init_reboot_state() == true)
    {
        LOG_DBG("Init DeepSleep\n");
        set_init_reboot_state(false);
    }
    else
    {
        WakeUpThird(TASK_SERVER_WAIT);
    }
}












